<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>努力努力奴林</title>
</head>
<body>
    
</body>
</html>
<script>
        //面试题？
            // 浅拷贝只是拷贝地址，
            // 深拷贝是是拷贝内容 
                    // 浅拷贝：只是简单的指针赋值     不会影响原来的
                    // 深拷贝：指针赋值，且内容拷贝   会影响原来的

            //对于字符串类型 浅拷贝是对值的复制 
            //对于对象来说   浅拷贝是对对象地址的复制
            //举例 A,B两个对象 A=B 改变A的属性 B也相对会发生改变因为AB指向的是同一个地址 
            
            //深拷贝是开辟一个新的栈 两个对象对应两个不同的地址 修改一个对象的属性 不会改变另一个对象的属性  


                    
// 浅拷贝——————————————————————————————————————————————————————————————————————————————————————————————————————————————
//方法1：Object.assign()   es6   如果源对象某个属性的值是对象，那么目标对象拷贝得到的是这个对象的引用。
        //数组
        let arr = [1, 2, 3, [10, 20, 30]];
        let newArr = Object.assign(arr);
        newArr[3][0] = 100;   //源对象的属性的值是一个对象/数组，Object.assign()拷贝得到的是这个对象的引用。这个对象的任何变化，都会反映到目标对象上面。
        console.log(arr);
        console.log(newArr);
            // [ 1, 2, 3, [ 100, 20, 30 ] ]
            // [ 1, 2, 3, [ 100, 20, 30 ] ]
            

        //对象
        let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
        let newObj = Object.assign(obj); //如果源对象某个属性的值是对象，那么目标对象拷贝得到的是这个对象的引用。
        newObj.c.m = 100;         
        console.log(obj);
        console.log(newObj);
            // { a: 1, b: 2, c: { m: 100, n: 20 } }
            // { a: 1, b: 2, c: { m: 100, n: 20 } }    
//方法2：扩展运算符 es6新增方法儿
        //数组
        let arr = [1, 2, 3, [10, 20, 30]];
        let newArr = [...arr];
        newArr[3][0] = 100;
        console.log(arr);
        console.log(newArr);
            // [ 1, 2, 3, [ 100, 20, 30 ] ]
            // [ 1, 2, 3, [ 100, 20, 30 ] ]


        //对象
        let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
        let newObj = { ...obj };
        newObj.c.m = 100;
        console.log(obj);
        console.log(newObj);
            // { a: 1, b: 2, c: { m: 100, n: 20 } }
            // { a: 1, b: 2, c: { m: 100, n: 20 } }

//方法3：遍历
        //数组
        let arr = [1, 2, 3, [10, 20, 30]];
        let newArr = [];
        arr.forEach((item) => {
        newArr.push(item);
        })
        newArr[3][0] = 100;
        console.log(arr);
        console.log(newArr);
            // [ 1, 2, 3, [ 100, 20, 30 ] ]
            // [ 1, 2, 3, [ 100, 20, 30 ] ]

        //对象
        let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
        let newObj = {};
        for(let key in obj){
        newObj[key] = obj[key];
        }
        newObj.c.m = 100;
        console.log(obj);
        console.log(newObj);
            // { a: 1, b: 2, c: { m: 100, n: 20 } }
            // { a: 1, b: 2, c: { m: 100, n: 20 } }    
// 深拷贝——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
// 方法2：JSON.parse() + JSON.stringify()
        let arr = [1, 2, 3, [10, 20, 30]];
        let newArr = JSON.parse(JSON.stringify(arr));
        newArr[3][0] = 100;
        console.log(arr);
        console.log(newArr);
            // [ 1, 2, 3, [ 10, 20, 30 ] ]
            // [ 1, 2, 3, [ 100, 20, 30 ] ]

// 方法3：  ...
        var a= [1,2]
        var b =[...a] 
        b[0]=100
        console.log(a) //[1,2]
        console.log(b) //[100,2]  
       
// 方法4： 循环
        var a =  [1,2]
        var a1 = []
        a.forEach(function(item,index){
          a1.push(item)
        })
        a[0] = 100
        console.log(a1) //[1,2]
        console.log(a) // [100,2]

//str 转  arr
    var a = [{a:1}]
		var obj= JSON.stringify(a)//arr转str
		console.log(obj)     //  [{"a":1}]   //黑色为str



//手写简单的深拷贝函数
            function deepClone(obj) {
              function isObject(para) {   //检测类型函数 
                return (typeof para === "object" || typeof para === "function") && para !== null;
              }

              if (!isObject(obj)) {       //调用检测类型函数 传入obj 抛出 
                return obj;
              }

              let cloneObj = Array.isArray(obj) ? [] : {};
              for (let i in obj) {
                if (obj.hasOwnProperty(i)) {
                  cloneObj[i] = isObject(obj[i]) ? deepClone(obj[i]) : obj[i];
                }
              }
              return cloneObj;                       
            }
                    let arr = [1, 2, 3, [10, 20, 30]];
                    let newArr = deepClone(arr);
                    newArr[3][0] = 100;
                    console.log(arr);
                    console.log(newArr);
                        // [ 1, 2, 3, [ 10, 20, 30 ] ]
                        // [ 1, 2, 3, [ 100, 20, 30 ] ]

                    let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
                    let newObj = deepClone(obj);
                    newObj.c.m = 100;
                    console.log(obj);
                    console.log(newObj);
                        // { a: 1, b: 2, c: { m: 10, n: 20 } }
                        // { a: 1, b: 2, c: { m: 100, n: 20 } }


  //采用递归 拷贝所有层级属性 
    function deepClone(obj){
          let objClone = Array.isArray(obj) ?[] :{};
          if(obj && typeof obj ==="object"){
            for(key in obj){
              if(obj.hasOwnProperty(key)){
                  //判断obj对象是否为对象 如果是 递归赋值 
                  if(obj[key] && typeof obj[key] === "object"){
                    objClone[key] = deepClone(obj[key])
                  }else{
                    //不是就简单复制  
                    objClone[key] = obj[key];
                  }
              }
            }
          }
          return objClone;
    }

    let arr = [1, 2, 3, [10, 20, 30]];
                    let newArr = deepClone(arr);
                    newArr[3][0] = 100;
                    console.log(arr);
                    console.log(newArr);
                        // [ 1, 2, 3, [ 10, 20, 30 ] ]
                        // [ 1, 2, 3, [ 100, 20, 30 ] ]

                    let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
                    let newObj = deepClone(obj);
                    newObj.c.m = 100;
                    console.log(obj);
                    console.log(newObj);
                        // { a: 1, b: 2, c: { m: 10, n: 20 } }
                        // { a: 1, b: 2, c: { m: 100, n: 20 } }











</script>